import json
import logging
import sys
import urllib.request
from zipfile import ZipFile


def download_url(url, fileName):
    u = urllib.request.urlopen(url)
    with open(fileName, "wb") as f:
        meta = u.info()
        fileSize = int(meta["content-length"])
        logging.info("Downloading: %s (%s bytes)" % (fileName, fileSize))

        downloadedSize = 0
        blockSize = 8192
        barSize = 30
        while True:
            buffer = u.read(blockSize)
            if not buffer:
                break

            downloadedSize += len(buffer)
            f.write(buffer)
            status = "\r"
            status += "#" * (downloadedSize * barSize // fileSize)
            status += " " * (barSize - downloadedSize * barSize // fileSize)
            status += "%10d  [%3.2f%%]" % (downloadedSize, downloadedSize * 100. / fileSize)
            # status += chr(8)*(len(status)+1)
            sys.stdout.write(status)
            sys.stdout.flush()

        sys.stdout.write("\n")


def unzip(fileName):
    logging.info("Extracting: " + fileName,)
    zip = ZipFile(fileName)
    zip.extractall()
    zip.close()
    logging.info(" [DONE]")


def parse_xml(xmlFile):
    logging.info("Processing: " + xmlFile,)
    if not xmlFile.endswith(".json"):
        return {}

    update_count = 0
    new_count = 0
    subDict = {}
    cveid = ""
    cvss = ""
    cweid = ""
    reference = []
    summary = ""

    with open(xmlFile, encoding='utf-8') as f:
        json_obj = json.load(f)

    cve_dict = json_obj["CVE_Items"]
    for cve in cve_dict:
        cveid = cve["cve"]["CVE_data_meta"]["ID"]
        try:
            cweid = cve["cve"]["problemtype"]["problemtype_data"][0]["description"][0]["value"]
        except:
            cweid = "CWE-000"

        try:
            cvss = cve["impact"]["baseMetricV2"]["cvssV2"]["baseScore"]
        except:
            cvss = "0.0"

        if cveid in subDict:
            update_count += 1
        else:
            new_count += 1

        subDict[cveid] = [cvss, cweid, reference, summary]

    logging.info("[Updated %s records, added %s new records]" % (update_count, new_count))
    return subDict
